/***************************************************************************
 *   Copyright (C) 2009 by Mayank Lahiri   *
 *   mlahiri@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <stdio.h>
#include <algorithm>
#include <string>
#include <string.h>
#include <map>
#include "readers.h"
#include "utils.h"
#include "tokenizer.h"

vector<string> id_to_label;

string &reader_retranslate(unsigned x) {
    return id_to_label[x];
}

//
// Reads a file of directed interactions, such as the Enron dataset
// i.e. plain text, space separated fields, one line per interaction, duplicates stripped away
//
// FORMAT: <junk> <time of interaction epoch seconds> <junk> <from label> <junk> <to label> <junk.....>
//
unsigned reader_enron(char *filename, vector<INTERACTION> &result, bool &directed, unsigned &nv)   {
    // setup
    map<string, unsigned> email_to_id;
    char buf[1024];
    unsigned lines_read = 0;
    INTERACTION intr;
    directed    = true;
    nv          = 0;
    result.clear();

    // start reading the thingy
    FILE *fp = fopen(filename, "r");
    Tokenizer tok;
    if(!fp) {
        fprintf(stderr, "Cannot open file '%s'\n", filename);
        return 0;
    }
    memset(buf, 0, 1024);
    while(fgets(buf, 1024, fp)) {
        lines_read++;
        chomp(buf);
        tok.tokenize(buf);
        if(tok.num_tokens() < 6)    {
            fprintf(stderr, "Line %d of file '%s' is invalid.\n", lines_read, filename);
            fclose(fp);
            return 0;
        }

        // 2nd token is epoch time
        string from(tok.token(3));
        string to(tok.token(5));
        if(email_to_id.find(from) == email_to_id.end()) {
            email_to_id[from] = nv++;
            id_to_label.push_back(from);
        }
        if(email_to_id.find(to) == email_to_id.end())   {
            email_to_id[to] = nv++;
            id_to_label.push_back(to);
        }
        intr.time = atoi(tok.token(1));
        intr.from = email_to_id[from];
        intr.to   = email_to_id[to];
        result.push_back(intr);
        memset(buf, 0, 1024);
    }
    fclose(fp);

    // sort the e-mail records
    sort(result.begin(), result.end());
    result.erase(unique(result.begin(), result.end()), result.end());

    return result.size();
}

//
// Reads a file of directed interactions, such as the Umass p2p dataset ("directed pairwise")
// i.e. plain text, space separated fields, one line per interaction, duplicates stripped away
//
// FORMAT: <time of interaction in epoch seconds> <from label> <to label> <junk.....>
//
unsigned reader_dirpair(char *filename, vector<INTERACTION> &result, bool &directed, unsigned &nv)  {
    // setup
    map<string, unsigned> email_to_id;
    char buf[1024];
    unsigned lines_read = 0;
    INTERACTION intr;
    directed    = true;
    nv          = 0;
    result.clear();

    // start reading the thingy
    FILE *fp = fopen(filename, "r");
    Tokenizer tok;
    if(!fp) {
        fprintf(stderr, "Cannot open file '%s'\n", filename);
        return 0;
    }
    memset(buf, 0, 1024);
    while(fgets(buf, 1024, fp)) {
        lines_read++;
        chomp(buf);
        tok.tokenize(buf);
        if(tok.num_tokens() < 3)    {
            fprintf(stderr, "Line %d of file '%s' is invalid.\n", lines_read, filename);
            fclose(fp);
            return 0;
        }

        // first three tokens are (time, from, to)
        string from(tok.token(1));
        string to(tok.token(2));
        if(email_to_id.find(from) == email_to_id.end()) {
            email_to_id[from] = nv++;
            id_to_label.push_back(from);
        }
        if(email_to_id.find(to) == email_to_id.end())   {
            email_to_id[to] = nv++;
            id_to_label.push_back(to);
        }
        intr.time = atoi(tok.token(0));
        intr.from = email_to_id[from];
        intr.to   = email_to_id[to];
        result.push_back(intr);
        memset(buf, 0, 1024);
    }
    fclose(fp);

    // sort the e-mail records
    sort(result.begin(), result.end());
    result.erase(unique(result.begin(), result.end()), result.end());
    return result.size();
}

//
// same as directed pair reader, but interactions are undirected
//
unsigned reader_undirpair(char *filename, vector<INTERACTION> &result, bool &directed, unsigned &num_verts) {
    unsigned x = reader_dirpair(filename, result, directed, num_verts);
    directed = false;
    return x;
}
